﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Threading;

namespace ZOIL.DataModel
{
    /// <summary>
    /// A util class for MVVM operations that occur frequently
    /// </summary>
    public static class MVVMUtil
    {
        private static readonly Dictionary<Object, BaseViewModel> ViewModels = new Dictionary<Object, BaseViewModel>();

        /// <summary>
        /// Creates a default view of the specified model
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static FrameworkElement CreateDefaultView(object model)
        {
            return CreateIndexedView(model, "default");
        }

        /// <summary>
        /// Creates the view that is stored under the given index for the specified model
        /// </summary>
        /// <param name="model"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static FrameworkElement CreateIndexedView(object model, string index)
        {
            var views = ViewFor.GetViewsFor(model.GetType());

            //try to get the view under the specified index
            if (views.ContainsKey(index))
            {
                var viewType = views[index];

                var view = (FrameworkElement) Activator.CreateInstance(viewType);

                var vm = ViewModelFor.GetViewModelFor(view.GetType());
                vm.Model = model;
                vm.View = view;
                view.DataContext = vm;
                ViewModels[model] = vm;

                // Apply AttachedProperties.RegisterCommandBindings here, so no xaml binding is necessary and bindings are established early enough
                //view.CommandBindings.AddRange(vm.CommandBindings);

                //Binding b = new Binding("CommandBindings");
                //b.Source = vm;
                //b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                //view.SetBinding(AttachedProperties.RegisterCommandBindingsProperty, b);

                view.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.Send);

                return view;
            }

            //if index was default, then there's no default view, so return null
            return index == "default" ? null : CreateDefaultView(model);
        }

        /// <summary>
        /// Creates the view that is stored under the given index for the specified model
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static BaseViewModel GetViewModel(object model)
        {
            if (model != null)
            {
                if (ViewModels.ContainsKey(model))
                {
                    return ViewModels[model];
                }
            }
            return null;
        }
    }
}
